home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
emulator
/
uae-0.000
/
uae-0
/
uae-0.6.0
/
os.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-05-26
|
14KB
|
675 lines
/*
* UAE - The Un*x Amiga Emulator
*
* OS specific functions
*
* (c) 1995 Bernd Schmidt
* (c) 1996 Marcus Sundberg
*/
#include "sysconfig.h"
#include "sysdeps.h"
#include "config.h"
#include "options.h"
#include "memory.h"
#include "custom.h"
#include "os.h"
#ifdef HAVE_LINUX_JOYSTICK_H
static int js0;
static int joystickpresent = 0;
struct JS_DATA_TYPE jscal;
void read_joystick(UWORD *dir, int *button)
{
static int minx = MAXINT, maxx = MININT,
miny = MAXINT, maxy = MININT;
int left = 0, right = 0, top = 0, bot = 0;
struct JS_DATA_TYPE buffer;
int len;
*dir = 0;
*button = 0;
if (!joystickpresent)
return;
len = read(js0, &buffer, sizeof(buffer));
if (len != sizeof(buffer))
return;
if (buffer.x < minx) minx = buffer.x;
if (buffer.y < miny) miny = buffer.y;
if (buffer.x > maxx) maxx = buffer.x;
if (buffer.y > maxy) maxy = buffer.y;
if (buffer.x < (minx + (maxx-minx)/3))
left = 1;
else if (buffer.x > (minx + 2*(maxx-minx)/3))
right = 1;
if (buffer.y < (miny + (maxy-miny)/3))
top = 1;
else if (buffer.y > (miny + 2*(maxy-miny)/3))
bot = 1;
if (left) top = !top;
if (right) bot = !bot;
*dir = bot | (right << 1) | (top << 8) | (left << 9);
*button = (buffer.buttons & 3) != 0;
}
void init_joystick(void)
{
js0 = open("/dev/js0", O_RDONLY);
if (js0 < 0)
return;
joystickpresent = 1;
}
void close_joystick(void)
{
if (joystickpresent)
close(js0);
}
#elif defined(__DOS__)
static int joystickpresent = 0;
void read_joystick(UWORD *dir, int *button)
{
static int minx = MAXINT, maxx = MININT,
miny = MAXINT, maxy = MININT;
int left = 0, right = 0, top = 0, bot = 0;
char JoyPort;
int laps, JoyX, JoyY;
*dir = 0;
*button = 0;
if (!joystickpresent)
return;
JoyX = 0;
JoyY = 0;
laps = 0;
__asm__ __volatile__("cli");
outportb(0x201, 0xff);
do {
JoyPort = inportb(0x201);
JoyX = JoyX + (JoyPort & 1);
JoyY = JoyY + ((JoyPort & 2) >> 1);
laps++;
} while(((JoyPort & 3) != 0) && (laps != 65535));
__asm__ __volatile__("sti");
if (JoyX < minx) minx = JoyX;
if (JoyY < miny) miny = JoyY;
if (JoyX > maxx) maxx = JoyX;
if (JoyY > maxy) maxy = JoyY;
if (JoyX < (minx + (maxx-minx)/3))
left = 1;
else if (JoyX > (minx + 2*(maxx-minx)/3))
right = 1;
if (JoyY < (miny + (maxy-miny)/3))
top = 1;
else if (JoyY > (miny + 2*(maxy-miny)/3))
bot = 1;
if (left) top = !top;
if (right) bot = !bot;
*dir = bot | (right << 1) | (top << 8) | (left << 9);
*button = ((~JoyPort) & 48) != 0;
}
void init_joystick(void)
{
int laps = 0;
char JoyPort;
__asm__ __volatile__("cli");
outportb(0x201, 0xff);
do {
JoyPort = inportb(0x201);
laps++;
} while(((JoyPort & 3) != 0) && (laps != 65535));
__asm__ __volatile__("sti");
if (laps != 65535)
joystickpresent = 1;
}
void close_joystick(void)
{
}
#else
void read_joystick(UWORD *dir, int *button)
{
*dir = 0;
*button = 0;
}
void init_joystick(void)
{
}
void close_joystick(void)
{
}
#endif
CPTR audlc[4], audpt[4];
UWORD audvol[4], audper[4], audlen[4], audwlen[4];
int audwper[4];
UWORD auddat[4];
int audsnum[4];
/* Audio states. This is not an exact representation of the Audio State Machine
* (HRM p. 166), but a simplification. To be honest, I don't completely
* understand that picture yet.
*/
int audst[4];
int sound_table[256][64];
static void init_sound_table16(void)
{
int i,j;
for (i = 0; i < 256; i++)
for (j = 0; j < 64; j++)
sound_table[i][j] = j * (BYTE)i;
}
static void init_sound_table8(void)
{
int i,j;
for (i = 0; i < 256; i++)
for (j = 0; j < 64; j++)
sound_table[i][j] = (j * (BYTE)i) / 256;
}
#ifdef LINUX_SOUND
#include <sys/ioctl.h>
#include <sys/soundcard.h>
static const int n_frames = 10;
/* The buffer is too large... */
static UWORD buffer[44100], *bufpt;
static UBYTE snddata[4];
static int frames = 0;
static int smplcnt = 0;
static int dsprate, dspbits, dspomit = 0;
static int sndbufsize;
static int sfd;
static int have_sound;
int init_sound (void)
{
int tmp;
int rate;
unsigned long formats;
sfd = open ("/dev/dsp", O_WRONLY);
have_sound = !(sfd < 0);
if (!have_sound) {
return 0;
}
ioctl (sfd, SNDCTL_DSP_GETFMTS, &formats);
tmp = 0x0004000D;
ioctl (sfd, SNDCTL_DSP_SETFRAGMENT, &tmp);
ioctl (sfd, SNDCTL_DSP_GETBLKSIZE, &sndbufsize);
#ifndef LINUX_SOUND_SLOW_MACHINE
dspbits = 16;
ioctl(sfd, SNDCTL_DSP_SAMPLESIZE, &dspbits);
ioctl(sfd, SOUND_PCM_READ_BITS, &dspbits);
if (dspbits != 16)
#endif
{
dspbits = 8;
ioctl(sfd, SNDCTL_DSP_SAMPLESIZE, &dspbits);
ioctl(sfd, SOUND_PCM_READ_BITS, &dspbits);
if (dspbits != 8)
return 0;
}
tmp = 0;
ioctl(sfd, SNDCTL_DSP_STEREO, &tmp);
#ifndef LINUX_SOUND_SLOW_MACHINE
dsprate = 0;
rate = 44100;
ioctl(sfd, SNDCTL_DSP_SPEED, &rate);
ioctl(sfd, SOUND_PCM_READ_RATE, &rate);
if (rate < 43000 || rate > 45000)
#endif
{
dsprate = 1;
rate = 22050;
ioctl(sfd, SNDCTL_DSP_SPEED, &rate);
ioctl(sfd, SOUND_PCM_READ_RATE, &rate);
/* Some soundcards return 22222 here. */
if (rate < 21000 || rate > 23000)
return 0;
}
if (dspbits == 16) {
/* Will this break horribly on Linux/Alpha? Possible... */
if (!(formats & AFMT_S16_LE))
return 0;
init_sound_table16 ();
} else {
if (!(formats & AFMT_U8))
return 0;
init_sound_table8 ();
}
printf ("Sound driver found and configured for %d bits at %d Hz, buffer is %d bytes\n",
dspbits, rate, sndbufsize);
audst[0] = audst[1] = audst[2] = audst[3] = 0;
bufpt = buffer;
frames = n_frames;
smplcnt = 0;
return 1;
}
static void channel_reload (int c)
{
audst[c] = 1;
audpt[c] = audlc[c];
audwper[c] = 0;
audwlen[c] = audlen[c];
audsnum[c] = 1;
}
void do_sound (void)
{
smplcnt -= 227;
while (smplcnt < 0) {
int i;
smplcnt += 80;
dspomit ^= dsprate;
for(i = 0; i < 4; i++) {
if (dmaen (1<<i)) {
if (audst[i] == 0) {
/* DMA was turned on for this channel */
channel_reload (i);
continue;
}
if (audwper[i] <= 0) {
audwper[i] += audper[i];
if (audst[i] == 1) {
/* Starting a sample, cause interrupt */
put_word (0xDFF09C, 0x8000 | (0x80 << i));
audst[i] = 2;
}
audsnum[i] ^= 1;
if (audsnum[i] == 0) {
auddat[i] = get_word (audpt[i]);
audpt[i] += 2;
audwlen[i]--;
if (audwlen[i] == 0) {
channel_reload (i);
}
}
}
if (adkcon & (0x11 << i)) {
snddata[i] = 0;
audsnum[i] ^= 2;
audsnum[i] |= 1;
if (i < 3) {
if (adkcon & (0x11 << i)) {
if (audsnum[i] & 2)
audvol[i+1] = auddat[i];
else
audper[i+1] = auddat[i];
} else if (adkcon & (1 << i)) {
audvol[i+1] = auddat[i];
} else {
audper[i+1] = auddat[i];
}
}
} else {
snddata[i] = audsnum[i] & 1 ? auddat[i] : auddat[i] >> 8;
}
audwper[i] -= 80;
} else
audst[i] = snddata[i] = 0;
}
if (dspbits == 16) {
if (dspomit == 0)
*bufpt++ = (sound_table[snddata[0]][audvol[0]]
+ sound_table[snddata[1]][audvol[1]]
+ sound_table[snddata[2]][audvol[2]]
+ sound_table[snddata[3]][audvol[3]]);
} else {
unsigned char *bp = (unsigned char *)bufpt;
if (dspomit == 0)
*bp++ = (sound_table[snddata[0]][audvol[0]]
+ sound_table[snddata[1]][audvol[1]]
+ sound_table[snddata[2]][audvol[2]]
+ sound_table[snddata[3]][audvol[3]] + 128);
bufpt = (UWORD *)bp;
}
if ((char *)bufpt - (char *)buffer >= sndbufsize) {
write(sfd, buffer, sndbufsize);
bufpt = buffer;
}
}
}
#elif defined(AF_SOUND)
#include <AF/AFlib.h>
/* The buffer is too large... */
static UWORD buffer[44100], *bufpt;
static UBYTE snddata[4];
static int smplcnt = 0;
static int dspbits = 0;
static int sndbufsize;
static AFAudioConn *aud;
static AC ac;
static long count = 0;
static long aftime;
static int rate;
static int freq_divisor;
static int have_sound;
int init_sound (void)
{
AFSetACAttributes attributes;
AFDeviceDescriptor *aDev;
int device;
aud = AFOpenAudioConn(NULL);
have_sound = !(aud == NULL);
if (!have_sound) {
return 0;
}
for(device = 0; device < ANumberOfAudioDevices(aud); device++) {
aDev = AAudioDeviceDescriptor(aud, device);
rate = aDev->playSampleFreq;
sndbufsize = (rate / 8) * 4;
if(aDev->inputsFromPhone == 0
&& aDev->outputsToPhone == 0
&& aDev->playNchannels == 1)
break;
}
if (device == ANumberOfAudioDevices(aud)) {
return 0;
}
dspbits = 16;
attributes.type = LIN16;
ac = AFCreateAC(aud, device, ACEncodingType, &attributes);
aftime = AFGetTime(ac);
if (dspbits == 16) {
init_sound_table16 ();
} else {
init_sound_table8 ();
}
freq_divisor = 44100 / rate;
audst[0] = audst[1] = audst[2] = audst[3] = 0;
bufpt = buffer;
smplcnt = 0;
printf ("Sound driver found and configured for %d bits at %d Hz, buffer is %d bytes\n", dspbits, rate, sndbufsize);
return 1;
}
static void channel_reload (int c)
{
audst[c] = 1;
audpt[c] = audlc[c];
audwper[c] = 0;
audwlen[c] = audlen[c];
audsnum[c] = 1;
}
void do_sound (void)
{
smplcnt -= 227;
while (smplcnt < 0) {
int i;
smplcnt += 80;
for(i = 0; i < 4; i++) {
if (dmaen (1<<i)) {
if (audst[i] == 0) {
/* DMA was turned on for this channel */
channel_reload (i);
continue;
}
if (audwper[i] <= 0) {
audwper[i] += audper[i];
if (audst[i] == 1) {
/* Starting a sample, cause interrupt */
put_word (0xDFF09C, 0x8000 | (0x80 << i));
audst[i] = 2;
}
audsnum[i] ^= 1;
if (audsnum[i] == 0) {
auddat[i] = get_word (audpt[i]);
audpt[i] += 2;
audwlen[i]--;
if (audwlen[i] == 0) {
channel_reload (i);
}
}
}
if (adkcon & (0x11 << i)) {
snddata[i] = 0;
audsnum[i] ^= 2;
audsnum[i] |= 1;
if (i < 3) {
if (adkcon & (0x11 << i)) {
if (audsnum[i] & 2)
audvol[i+1] = auddat[i];
else
audper[i+1] = auddat[i];
} else if (adkcon & (1 << i)) {
audvol[i+1] = auddat[i];
} else {
audper[i+1] = auddat[i];
}
}
} else {
snddata[i] = audsnum[i] & 1 ? auddat[i] : auddat[i] >> 8;
}
audwper[i] -= 80;
} else
audst[i] = snddata[i] = 0;
}
if ((count++ % frq_divisor) == 0) {
long size;
*bufpt++ = (sound_table[snddata[0]][audvol[0]]
+ sound_table[snddata[1]][audvol[1]]
+ sound_table[snddata[2]][audvol[2]]
+ sound_table[snddata[3]][audvol[3]];
size = (char *)bufpt - (char *)buffer;
if (size >= sndbufsize) {
if (AFGetTime(ac) > aftime)
aftime = AFGetTime(ac);
AFPlaySamples(ac, aftime, size, (unsigned char*) buffer);
aftime += size / 2;
bufpt = buffer;
}
}
}
}
#elif defined(__mac__)
#include <Sound.h>
static SndChannelPtr newChannel;
static ExtSoundHeader theSndBuffer;
static SndCommand theCmd;
static const int n_frames = 10;
/* The buffer is too large... */
static UWORD buffer0[44100], buffer1[44100], *bufpt;
static UBYTE snddata[4];
static int frames = 0;
static int smplcnt = 0;
static long count = 0;
static int have_sound;
static int sndbufsize=44100;
static int nextbuf=0;
static Boolean sFlag=true;
int init_sound (void)
{
if (SndNewChannel(&newChannel, sampledSynth, initMono, NULL))
return 0;
init_sound_table8 ();
smplcnt = 0;
bufpt = buffer0;
return 1;
}
static void channel_reload (int c)
{
audst[c] = 1;
audpt[c] = audlc[c];
audwper[c] = 0;
audwlen[c] = audlen[c];
audsnum[c] = 1;
}
void do_sound (void)
{
unsigned char *bp;
smplcnt -= 227;
while (smplcnt < 0) {
int i;
smplcnt += 80;
for(i = 0; i < 4; i++) {
if (dmaen (1<<i)) {
if (audst[i] == 0) {
/* DMA was turned on for this channel */
channel_reload (i);
continue;
}
if (audwper[i] <= 0) {
audwper[i] += audper[i];
if (audst[i] == 1) {
/* Starting a sample, cause interrupt */
put_word (0xDFF09C, 0x8000 | (0x80 << i));
audst[i] = 2;
}
audsnum[i] ^= 1;
if (audsnum[i] == 0) {
auddat[i] = get_word (audpt[i]);
audpt[i] += 2;
audwlen[i]--;
if (audwlen[i] == 0) {
channel_reload (i);
}
}
}
if (adkcon & (0x11 << i)) {
snddata[i] = 0;
audsnum[i] ^= 2;
audsnum[i] |= 1;
if (i < 3) {
if (adkcon & (0x11 << i)) {
if (audsnum[i] & 2)
audvol[i+1] = auddat[i];
else
audper[i+1] = auddat[i];
} else if (adkcon & (1 << i)) {
audvol[i+1] = auddat[i];
} else {
audper[i+1] = auddat[i];
}
}
} else {
snddata[i] = audsnum[i] & 1 ? auddat[i] : auddat[i] >> 8;
}
audwper[i] -= 80;
} else
audst[i] = snddata[i] = 0;
}
bp = (unsigned char *)bufpt;
*bp++ = (sound_table[snddata[0]][audvol[0]]
+ sound_table[snddata[1]][audvol[1]]
+ sound_table[snddata[2]][audvol[2]]
+ sound_table[snddata[3]][audvol[3]] + 128);
bufpt = (UWORD *)bp;
if (nextbuf == 0) {
if ((char *)bufpt - (char *)buffer0 >= sndbufsize) {
nextbuf++;
bufpt = buffer1;
theSndBuffer.samplePtr = (Ptr)buffer0;
theSndBuffer.numChannels = 1;
theSndBuffer.sampleRate = 0xac440000;
theSndBuffer.encode = extSH;
theSndBuffer.numFrames = sndbufsize;
theSndBuffer.sampleSize = 8;
theCmd.param1 = 0;
theCmd.param2 = (long)&theSndBuffer;
theCmd.cmd = bufferCmd;
SndDoCommand(newChannel, &theCmd, false);
}
} else {
if ((char *)bufpt - (char *)buffer1 >= sndbufsize) {
nextbuf=0;
bufpt = buffer0;
theSndBuffer.samplePtr = (Ptr)buffer1;
theSndBuffer.numChannels = 1;
theSndBuffer.sampleRate = 0xac440000;
theSndBuffer.encode = extSH;
theSndBuffer.numFrames = sndbufsize;
theSndBuffer.sampleSize = 8;
theCmd.param1 = 0;
theCmd.param2 = (long)&theSndBuffer;
theCmd.cmd = bufferCmd;
SndDoCommand(newChannel, &theCmd, false);
}
}
}
}
#else
int init_sound (void)
{
return 1;
}
void do_sound (void)
{
}
#endif